<script setup>
import { ref, onMounted, onUnmounted, defineProps, defineEmits, watch, nextTick } from 'vue';

// 定义组件属性
const props = defineProps({
  // 控制模态框显示/隐藏
  visible: {
    type: Boolean,
    default: false
  },
  // 初始位置
  initialPosition: {
    type: Object,
    default: () => ({ top: '50%', left: '50%' })
  },
  // 模态框标题
  title: {
    type: String,
    default: '提示'
  },
  // 模态框宽度
  width: {
    type: String,
    default: '500px'
  },
  // 是否可拖拽
  draggable: {
    type: Boolean,
    default: true
  },
  // 是否显示关闭按钮
  showClose: {
    type: Boolean,
    default: true
  }
});

// 定义事件
const emit = defineEmits(['update:visible', 'close']);

// 模态框位置和拖拽状态
const position = ref({ top: 0, left: 0 });
const isDragging = ref(false);
const startPos = ref({ x: 0, y: 0 });
const mask = ref(null);
const modalRef = ref(null);
const headerRef = ref(null);

// 关闭模态框
const closeModal = () => {
  emit('update:visible', false);
  emit('close');
};

// 点击模态框外部关闭
const handleOverlayClick = (e) => {
  if (e.target === mask.value) {
    closeModal();
  }
};

// 将百分比位置转换为像素位置
const convertPositionToPixels = () => {
  if (!modalRef.value) return;

  const { top, left } = props.initialPosition;
  const { innerWidth, innerHeight } = window;

  position.value.top = typeof top === 'string' && top.endsWith('%') 
    ? (parseFloat(top) / 100) * innerHeight - (modalRef.value.offsetHeight / 2)
    : parseInt(top) || 0;
  position.value.left = typeof left === 'string' && left.endsWith('%') 
    ? (parseFloat(left) / 100) * innerWidth - (modalRef.value.offsetWidth / 2)
    : parseInt(left) || 0;
};

// 拖拽相关方法
const handleMouseDown = (e) => {
  if (!props.draggable || e.target !== headerRef.value) return;

  isDragging.value = true;
  startPos.value = {
    x: e.clientX - position.value.left,
    y: e.clientY - position.value.top
  };

  // 添加鼠标样式
  document.body.style.cursor = 'grabbing';
};

const handleMouseMove = (e) => {
  if (!isDragging.value) return;
  
  requestAnimationFrame(() => {
    const newLeft = e.clientX - startPos.value.x;
    const newTop = e.clientY - startPos.value.y;

    // 限制模态框在可视区域内
    const maxLeft = window.innerWidth - modalRef.value.offsetWidth;
    const maxTop = window.innerHeight - modalRef.value.offsetHeight;

    position.value.left = Math.max(0, Math.min(newLeft, maxLeft));
    position.value.top = Math.max(0, Math.min(newTop, maxTop));
  });
};

const handleMouseUp = () => {
  if (!isDragging.value) return;

  isDragging.value = false;
  document.body.style.cursor = '';
};

// 监听窗口大小变化，调整模态框位置
const handleResize = () => {
  if (!modalRef.value) return;

  const maxLeft = window.innerWidth - modalRef.value.offsetWidth;
  const maxTop = window.innerHeight - modalRef.value.offsetHeight;

  position.value.left = Math.min(position.value.left, maxLeft);
  position.value.top = Math.min(position.value.top, maxTop);
};

// 监听事件
onMounted(() => {
  convertPositionToPixels();
  window.addEventListener('mousemove', handleMouseMove);
  window.addEventListener('mouseup', handleMouseUp);
  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  window.removeEventListener('mousemove', handleMouseMove);
  window.removeEventListener('mouseup', handleMouseUp);
  window.removeEventListener('resize', handleResize);
  document.body.style.cursor = '';
});

// 监听visible属性变化
watch(
  () => props.visible,
  (newVal) => {
    if (newVal) {
      nextTick(convertPositionToPixels)
    }
  }
);
</script>

<template>
  <teleport to="body">
    <div v-if="visible" ref="mask" class="my-modal-overlay" @click="handleOverlayClick">
      <div
        ref="modalRef"
        class="my-modal"
        :style="{ width, top: position.top + 'px', left: position.left + 'px' }"
      >
        <div ref="headerRef" class="my-modal-header"
             :class="{ 'cursor-move': draggable }"
             @mousedown="handleMouseDown">
          <div class="my-modal-title">{{ title }}</div>
          <button
            v-if="showClose"
            class="my-modal-close"
            @click="closeModal"
          >
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none"
                 xmlns="http://www.w3.org/2000/svg">
              <path d="M12 4L4 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                    stroke-linejoin="round"/>
              <path d="M4 4L12 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
                    stroke-linejoin="round"/>
            </svg>
          </button>
        </div>
        <div class="my-modal-content">
          <slot></slot>
        </div>
        <div class="my-modal-footer" v-if="$slots.footer">
          <slot name="footer"></slot>
        </div>
      </div>
    </div>
  </teleport>
</template>

<style scoped lang="scss">
.my-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(2px);
  animation: fadeIn 0.3s ease;
}

.my-modal {
  background-color: rgba(17, 25, 40, 0.75);
  border: 1px solid rgba(127, 219, 255, 0.3);
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(127, 219, 255, 0.3);
  color: #7fdbff;
  position: absolute;
  overflow: hidden;
  // transition: all 0.3s ease;
  // transform: translate(-50%, -50%);
}

.my-modal-header {
  padding: 12px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(127, 219, 255, 0.2);
  background: linear-gradient(to right, rgba(0, 116, 217, 0.1), rgba(0, 116, 217, 0.05));
  user-select: none;
}

.my-modal-title {
  font-size: 16px;
  font-weight: 500;
  color: #7fdbff;
  text-shadow: 0 0 5px rgba(127, 219, 255, 0.5);
}

.my-modal-close {
  background: none;
  border: none;
  color: #7fdbff;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.2s;

  &:hover {
    background-color: rgba(127, 219, 255, 0.1);
    color: #0074d9;
  }
}

.my-modal-content {
  padding: 16px;
  max-height: calc(100vh - 160px);
  overflow-y: auto;
  color: #e0e0e0;
}

.my-modal-footer {
  padding: 12px 16px;
  border-top: 1px solid rgba(127, 219, 255, 0.2);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 滚动条样式 */
.my-modal-content::-webkit-scrollbar {
  width: 6px;
}

.my-modal-content::-webkit-scrollbar-track {
  background: rgba(127, 219, 255, 0.1);
  border-radius: 3px;
}

.my-modal-content::-webkit-scrollbar-thumb {
  background: rgba(127, 219, 255, 0.5);
  border-radius: 3px;
}

.my-modal-content::-webkit-scrollbar-thumb:hover {
  background: rgba(127, 219, 255, 0.8);
}
</style>